﻿using System;
using System.Collections.Concurrent;
using System.Reflection;
using System.Resources;

namespace Epic.Core
{
    public static class ResourceUtility
    {
#pragma warning disable 1591

        private static ConcurrentDictionary<Tuple<string, Type>, Lazy<ResourceManager>> smResManCache =
            new ConcurrentDictionary<Tuple<string, Type>, Lazy<ResourceManager>>();

        private static ResourceManager GetResourceManagerInternal(string qualifiedName, string baseName, Assembly assembly, Type usingResourceSet)
        {
            var key = Tuple.Create(qualifiedName.ToUpperInvariant(), usingResourceSet);

            var lazy = new Lazy<ResourceManager>(() => new ResourceManager(baseName, assembly, usingResourceSet));
            if (!smResManCache.TryAdd(key, lazy))
                lazy = smResManCache[key];

            return lazy.Value;
        }

        public static ResourceManager GetResourceManager(this Type type, Type usingResourceSet = null)
        {
            return GetResourceManagerInternal(type.AssemblyQualifiedName, type.FullName, type.Assembly, usingResourceSet);
        }

        public static ResourceManager GetResourceManager(this string qualifiedName, Type usingResourceSet = null)
        {
            // there is never a chance to locate the assembly where the actual class which used the attributes defined
            // so just forget it
            return GetResourceManager(Type.GetType(qualifiedName), usingResourceSet);
        }

        public static ResourceManager GetResourceManager(this Assembly assembly, string baseName, Type usingResourceSet = null)
        {
            return GetResourceManagerInternal(baseName.Trim() + ", " + assembly.FullName, baseName, assembly, usingResourceSet);
        }
    }
}
